import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:xim/common/model/file_type.dart';
import 'package:xim/common/style/colors.dart';
import 'package:xim/common/util/collection.dart';
import 'package:xim/common/util/device.dart';
import 'package:xim/common/util/system.dart';
import 'package:xim/config/route_config.dart';
import 'package:xim/http/apis.dart';
import 'package:xim/http/apis/secret/secret_model.dart';
import 'package:xim/http/apis/user/user_model.dart';
import 'package:xim/router/index.dart';
import 'package:xim/screen/message_list_screen/page/chat_detail_page/chat_detail_controller.dart';
import 'package:xim/widget/common/state.dart';
import 'package:xim/widget/dash_chat_2/dash_chat_2.dart';
import 'package:xim/screen/message_list_screen/widget/chat_avatar.dart';
import 'package:xim/screen/message_list_screen/widget/chat_bottom_action_panel.dart';
import 'package:xim/screen/message_list_screen/widget/chat_bottom_face_panel.dart';
import 'package:xim/screen/message_list_screen/widget/date_separator.dart';
import 'package:xim/screen/message_list_screen/widget/message_row_widget.dart';
import 'package:mime/mime.dart';
import 'package:xim/common/get_style_view.dart';
import 'package:xim/widget/dash_chat_2/extension/ChatMessageExtension.dart';

typedef SendFile = void Function(MediaType type, String path);

class ChatDetailStyle extends Style with AppBarMixin {
  var controller = Get.find<ChatDetailController>();

  final bgColor =
      ModelColor(darkColor: const Color(0xff111111), lightColor: const Color(0xffededed));
  final textColor = ModelColor(darkColor: Colors.white, lightColor: Colors.black);
  final bottomBarBgColor =
      ModelColor(darkColor: const Color(0xff1e1e1e), lightColor: const Color(0xfff7f7f7));
  final appBarFontColor = ModelColor(darkColor: Colors.white, lightColor: Colors.black);
  final bottomBarDividerColor =
      ModelColor(darkColor: Colors.transparent, lightColor: const Color(0xd2d2d2d2));
  final panelIconColor = ModelColor(darkColor: Colors.white, lightColor: Colors.black);
  final secPanelIconColor =
      ModelColor(darkColor: const Color(0xff2b2b2b), lightColor: Colors.white);
  final bottomInputFillColor =
      ModelColor(darkColor: const Color(0xff292929), lightColor: const Color(0xffffffff));

  @override
  List<ModelColor> get modelColors => [
        appBarColor,
        bgColor,
        textColor,
        weakTextColor,
        bottomBarBgColor,
        bottomBarBgColor,
        appBarFontColor,
        bottomBarDividerColor,
        panelIconColor,
        secPanelIconColor,
        bottomInputFillColor,
        bgColor
      ];

  /// 聊天输入框 水平 margin
  final double inputHorizontalMargin = 4;

  /// 消息输入框最大行数
  final int inputMaxLines = 2;

  /// 底部输入框 focusNode
  final FocusNode focusNode = FocusNode();

  /// 聊天输入框 placeholder 提示文本
  final String inputHintText = "Write a message...";

  /// 会话密钥弹出框表格title样式
  TextStyle get secretKeyTableTitleStyle =>
      TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: textColor.color);

  /// 会话密钥弹出框表格数据样式
  TextStyle get secretKeyTableTextStyle => TextStyle(fontSize: 14, color: textColor.color);

  /// 会话密钥弹出框表格操作控件样式
  TextStyle get secretKeyTableActionStyle =>
      const TextStyle(fontSize: 14, color: StyleColor.textLinkColor, fontWeight: FontWeight.bold);

  Widget secretKeyTableTitleDivider = const Divider();
  Widget secretKeyTableItemDivider = const Divider();
  final double secretKeyTableGap = 8;

  MessageListOptions get messageListOptions => MessageListOptions(
      showDateSeparator: true,
      dateSeparatorBuilder: (DateTime date) => DateSeparator(date: date),
      scrollPhysics: const BouncingScrollPhysics(),
      separatorFrequency: SeparatorFrequency.hours,
      scrollController: scrollController,
      bgColor: bgColor.color);

  @override
  TextStyle get appBarTitleStyle => TextStyle(color: appBarFontColor.color, fontSize: 16);

  @override
  IconThemeData get iconTheme => IconThemeData(color: appBarFontColor.color);

  @override
  double get elevation => 0.15;

  @override
  Color get appBarBgColor => bgColor.color;

  @override
  String get appBarTitle => controller.sessionInfo.name;

  @override
  List<Widget> get appBarActions => [
        IconButton(
            onPressed: () => Routers.toChatInfo(controller.sessionId),
            icon: const Icon(
              Icons.more_horiz,
            ))
      ];

  /// 底部栏
  List<BottomPanel> bottomPanels(SendFile sendFile) => [
        BottomPanel(
            0,
            ChatBottomFacePanel(
              height: 500,
              bgColor: bgColor.color,
            ),
            300,
            Icon(
              Icons.mood,
              color: panelIconColor.color,
            )),
        BottomPanel(
          1,
          ChatBottomActionPanel(
            height: 200,
            imageSelected: (f) async {
              var mimeType = lookupMimeType(f.path);
              MediaType type = MediaType.file;
              if (mimeType == null) {
              } else if (mimeType.toLowerCase().contains("video")) {
                type = MediaType.video;
              } else if (mimeType.toLowerCase().contains("image")) {
                type = MediaType.image;
              }
              sendFile(type, f.path);
            },
          ),
          200,
          Icon(Icons.add_circle_outline, color: panelIconColor.color),
        ),
      ];

  /// 自定义 聊天对话框底部输入框样式
  InputDecoration get bottomInputDecoration => InputDecoration(
      isDense: true,
      hintText: inputHintText,
      filled: true,
      fillColor: bottomInputFillColor.color,
      contentPadding: const EdgeInsets.only(
        left: 18,
        top: 10,
        bottom: 10,
      ),
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(32),
        borderSide: const BorderSide(
          width: 0,
          style: BorderStyle.none,
        ),
      ));

  List<Widget> _trailing(SendFile sendFile, BuildContext context) => bottomPanels(sendFile)
      .where((element) => element.condition)
      .map((e) => InkWell(
          onTap: () => e == controller.currBottomPanel.value
              ? controller.closeBottomPanel()
              : controller.openBottomPanel(e, inputOptions(sendFile, context), context: context),
          child: e.icon))
      .toList();

  InputOptions inputOptions(SendFile sendFile, BuildContext context) => InputOptions(
      inputToolbarStyle: BoxDecoration(
          color: bottomBarBgColor.color,
          border: Border(
            top: BorderSide(width: 1.2, color: bottomBarDividerColor.color),
          )),
      // 自定义发送Icon
      sendButtonBuilder: (send) => GestureDetector(
            onTap: send,
            child: _sendMsgBtn,
          ),
      inputToolbarMargin: const EdgeInsets.all(0),
      inputDecoration: bottomInputDecoration,
      inputTextStyle: const TextStyle(fontSize: 14),
      showTraillingBeforeSend: true,
      focusNode: focusNode,
      inputHorizontalMargin: 8,
      inputMaxLines: inputMaxLines,
      trailing: _trailing(sendFile, context),
      textController: TextEditingController(),
      leading: [
        GestureDetector(
          onTap: () => _showSecretKeyBottomSheet(context, controller.sessionSecretKeys,
              onCreate: () => controller.createSessionSecretKeys(),
              detailOnClick: Routers.toSessionSecurityKeyDetailPage,
              onUsing: controller.updateCurrSecretKey),
          child: Container(
            height: 25,
            constraints: const BoxConstraints(
              minWidth: 15,
              maxWidth: 25,
            ),
            decoration: BoxDecoration(
              color: Theme.of(context).splashColor,
              borderRadius: const BorderRadius.all(Radius.circular(3)),
            ),
            child: Center(
              child: Text(
                "V${controller.currSecretKeyModel.secretKeyVersion}",
                style: const TextStyle(fontSize: 10),
              ),
            ),
          ),
        )
      ],
      onTextChange: (String value) {
        bool hasMessage = value.trim() != "";
        // 文本输入
        // setState(() {
        //   bottomPanels[bottomPanels.length - 1].condition = !hasMessage;
        // });
      });

  /// send
  Widget get _sendMsgBtn => Container(
        margin: const EdgeInsets.only(left: 3),
        padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
        decoration: const BoxDecoration(
            color: Colors.blueAccent, borderRadius: BorderRadius.all(Radius.circular(8))),
        child: const Text(
          "发送",
          style: TextStyle(fontWeight: FontWeight.w400),
        ),
      );

  /// 密钥选择弹窗
  void _showSecretKeyBottomSheet(BuildContext context, List<SessionSecretKeyModel> items,
      {required void Function() onCreate,
      required void Function(int secKeyId) detailOnClick,
      required void Function(int secKeyId) onUsing}) {
    bottomSheet(context, _sessionSecretKeyTable(items, onCreate, detailOnClick, onUsing),
        padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 24),
        bgColor: secPanelIconColor.color);
  }

  /// 密钥列表弹窗
  Widget _sessionSecretKeyTable(List<SessionSecretKeyModel> items, void Function() onCreate,
          void Function(int secKeyId) detailOnClick, void Function(int secKeyId) onUsing) =>
      Column(
        children: [
          Expanded(
            child: Row(
              children: [
                Expanded(
                  child: _sessionSecretKeyTableData(items),
                ),
                _sessionSecretKeyTableOption(items, detailOnClick, onUsing)
              ],
            ),
          ),
          _sessionSecretKeyTableNavBar(onCreate, secretKeyTableTextStyle)
        ],
      );

  /// 会话密钥弹出框表格控件
  Widget _sessionSecretKeyTableOption(List<SessionSecretKeyModel> items,
          void Function(int secKeyId) detailOnClick, void Function(int secKeyId) onUsing) =>
      Column(
        children: [
          Text(
            "操作",
            style: secretKeyTableTitleStyle,
          ),
          secretKeyTableTitleDivider,
          ...items
              .map((e) => e.secretKeyVersion != controller.currSecretKeyModel.secretKeyVersion
                  ? Row(
                      children: [
                        InkWell(
                            onTap: () => Routers.toChat(e.id),
                            child: Text(
                              "详情",
                              style: secretKeyTableActionStyle,
                            )),
                        const SizedBox(
                          width: 6,
                        ),
                        InkWell(
                            onTap: () {
                              onUsing.call(e.id);
                              // toast("应用成功", context: context);
                            },
                            child: Text(
                              "使用",
                              style: secretKeyTableActionStyle,
                            ))
                      ],
                    )
                  : InkWell(
                      onTap: () => detailOnClick
                          .call(e.id), // context.push("/session/secretKey/${e.id}/detail"),
                      child: Text(
                        "详情",
                        style: secretKeyTableActionStyle,
                      )))
              .map((e) => e as Widget)
              .splitJoin(secretKeyTableItemDivider)
              .toList()
        ],
      );

  /// 会话密钥弹出框表格数据
  Widget _sessionSecretKeyTableData(List<SessionSecretKeyModel> items) => Row(
        children: [
          Column(
            children: [
              // title
              Text(
                "版本",
                style: secretKeyTableTitleStyle,
              ),
              secretKeyTableTitleDivider,
              ...items
                  .map((e) => Text(
                        e.secretKeyVersion.toString(),
                        style: secretKeyTableTextStyle,
                      ))
                  .map((e) => e as Widget)
                  .splitJoin(secretKeyTableItemDivider)
                  .toList()
            ],
          ),
          SizedBox(
            width: secretKeyTableGap,
          ),
          Column(
            children: [
              Text("密钥", style: secretKeyTableTitleStyle),
              secretKeyTableTitleDivider,
              ...items
                  .map((e) => Text(
                        e.secretKey.ellipsis(20),
                        style: secretKeyTableTextStyle,
                      ))
                  .map((e) => e as Widget)
                  .splitJoin(secretKeyTableItemDivider)
                  .toList()
            ],
          ),
          SizedBox(
            width: secretKeyTableGap,
          ),
        ],
      );

  /// 会话密钥弹出框操作栏
  Widget _sessionSecretKeyTableNavBar(void Function() onCreate, TextStyle textStyle) => Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ElevatedButton(
              onPressed: () async {
                onCreate.call();
                Routers.back();
              },
              child: const Text(
                "新建",
                style: TextStyle(fontSize: 12),
              )),
          ElevatedButton(
            onPressed: () => Get.back(),
            style: ButtonStyle(
              backgroundColor: MaterialStateProperty.all(secPanelIconColor.color),
            ),
            child: Text(
              "返回",
              style: TextStyle(color: textStyle.color, fontSize: 12),
            ),
          ),
        ],
      );

  /// 消息菜单栏
  MessageOptions messageOptions(BuildContext context) => MessageOptions(
      borderRadius: 6,
      currentUserTextColor: Colors.black,
      textColor: PlatformUtils.isDarkMode(context) ? Colors.white : Colors.black,
      onLongPressMessage: (msg) {
        // 展示消息菜单
        msg.customProperties ??= {};
        // msg.customProperties!['showMenu'] = true;
        msg.customProperties!['selectAll'] = true;
      },
      // 媒体消息
      messageMediaBuilder: (message, previousMessage, nextMessage, messageOptions) {
        return MediaContainer(
          message: message,
          isOwnMessage: message.user.id == controller.currChatUser.id,
          messageOptions: messageOptions,
        );
      },
      // 点击媒体消息
      onTapMedia: (ChatMedia media, ChatMessage msg) {
        if (media.type == MediaType.video) {
          // 视频
          var attachment = msg.attachment;
          if (attachment != null) {
            Routers.toMediaView(MediaView(attachment, FileType.video, msg.secretKey));
          }
        }
        // var ciphertextAESKey = msg.secretKey;
        // var plaintextAESKey = decodeByPrivateKeySync(
        //     controller.userPrivateKey,
        //     ciphertextAESKey.secretKey
        // );
        // var fileName = media.fileName;
        // var mediaView = MediaView.of(fileName, plaintextAESKey: plaintextAESKey);
        // Routers.toMediaView(mediaView);
      },
      imageProvider: (url, message) {
        /// 图片解密
        // var ciphertextAESKey = message.secretKey;
        // var plaintextAESKey = decodeByPrivateKeySync(
        //     controller.userPrivateKey,
        //     ciphertextAESKey.secretKey
        // );
        // return EncryptNetWorkImageProvider(url, plaintextAESKey);
        return NetworkImage(url);
      },
      messageRowBuilder: (msg, preMsg, nextMsg, isAfterDateSeparator, isBeforeDateSeparator,
              {MessageOptions? messageOptions}) =>
          // 消息渲染
          MessageRowWidget(
            message: msg,
            currentUser: controller.currChatUser,
            previousMessage: preMsg,
            nextMessage: nextMsg,
            isAfterDateSeparator: isAfterDateSeparator,
            isBeforeDateSeparator: isBeforeDateSeparator,
            messageOptions: messageOptions!,
          ),
      messageDecorationBuilder: (message, p, n) => messageDecoration(message, context),
      showOtherUsersAvatar: true,
      showCurrentUserAvatar: true,
      showOtherUsersName: false,
      marginSameAuthor: const EdgeInsets.only(top: 10),
      marginDifferentAuthor: const EdgeInsets.only(top: 10),
      onPressAvatar: (ChatUser chatUser) => Routers.toProfilePublicPage(chatUser.account!),
      avatarBuilder: (ChatUser chatUser, Function? pressAvatar, Function? longPressAvatar) {
        return ChatAvatar(
            user: chatUser, onLongPressAvatar: longPressAvatar, onPressAvatar: pressAvatar);
      });

  /// 自定义消息框样式
  BoxDecoration messageDecoration(ChatMessage message, BuildContext context) {
    Color bgColor = Colors.blueAccent;
    if (message.user.id != controller.currChatUser.id) {
      bgColor = Colors.white;
      if (PlatformUtils.isDarkMode(context)) {
        bgColor = const Color(0xff2c2c2c);
      }
    }
    return BoxDecoration(
      color: bgColor,
      borderRadius: BorderRadius.circular(7),
    );
  }
}

/// 聊天视图 滚动控制器
final ScrollController scrollController = ScrollController();

/// 底部面板
class BottomPanel {
  /// 排序优先级
  final int sortedOrder;

  /// 面板内容
  final Widget panel;

  /// 面板高度
  final double height;

  /// 展示Icon
  Icon icon;

  /// 条件展示
  bool condition;

  BottomPanel(this.sortedOrder, this.panel, this.height, this.icon, {this.condition = true});
}
